using Publicuse.Appication;
using Publicuse.Autofac;
using Publicuse.Entity;
using Publicuse.Entity.AttributeUtil;
using Publicuse.Interface;
using Publicuse.Util;
using Publicuse.Util.QuartZ;
using Quartz;
using Quartz.Impl.Matchers;
using Quartz.Impl.Triggers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Publicuse.Application
{
    public class QuartzApplication
    {
        private static BaesApplication baseApplication;
        private static QuartzApplication userApplication;

        public static QuartzApplication GetApplication(ServiceContainer container)
        {
            baseApplication = new BaesApplication(container);
            return userApplication;
        }

        static QuartzApplication()
        {
            userApplication = new QuartzApplication();
        }

        /// <summary>
        /// 获取后台作业信息列表
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<CommonResult> GetList(QuzrtTaskOptions query)
        {
            return await baseApplication.GetListByExpression<QuzrtTaskOptions>(query, query.pageIndex, query.pageSize, o => o.Id, false);

        }

        /// <summary>
        /// 根据作业分组和任务名称获取作业状态
        /// </summary>
        /// <param name="schedulerFactory"></param>
        /// <param name="GroupName"></param>
        /// <param name="TaskName"></param>
        /// <returns></returns>
        public async Task<CommonResult> GetJobStatus(ISchedulerFactory schedulerFactory, string GroupName, string TaskName)
        {
            return await Task.Factory.StartNew(() =>
            {
                CommonResult result = new CommonResult();
                IScheduler scheduler = schedulerFactory.GetScheduler().GetAwaiter().GetResult();
                List<JobKey> jobKeys = scheduler.GetJobKeys(GroupMatcher<JobKey>.GroupEquals(GroupName)).Result.ToList();
                if (jobKeys == null || jobKeys.Count() == 0)
                {
                    result.data = $"未启动";
                    return result;
                }
                JobKey jobKey = jobKeys.Where(s => scheduler.GetTriggersOfJob(s).Result.Any(x => (x as CronTriggerImpl).Name == TaskName)).FirstOrDefault();
                if (jobKey == null)
                {
                    result.data = $"未启动";
                    return result;
                }
                var triggers = scheduler.GetTriggersOfJob(jobKey).GetAwaiter().GetResult();
                ITrigger trigger = triggers?.Where(x => (x as CronTriggerImpl).Name == TaskName).FirstOrDefault();
                if (trigger == null)
                {
                    result.data = $"未启动";
                    return result;
                }
                TriggerKey triggerKey = new TriggerKey(TaskName,GroupName);
                var state = scheduler.GetTriggerState(triggerKey).GetAwaiter().GetResult();
                switch (state)
                {
                    case TriggerState.Normal:
                        result.data = "运行中";
                        break;
                    case TriggerState.Paused:
                        result.data = "暂停";
                        break;
                    case TriggerState.Complete:
                        result.data = "完成";
                        break;
                    case TriggerState.Error:
                        result.data = "错误";
                        break;
                    case TriggerState.Blocked:
                        result.data = "阻塞";
                        break;
                    case TriggerState.None:
                        result.data = "未运行";
                        break;
                }
                return result;
            });
        }

        /// <summary>
        /// 新增修改后台作业信息
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public async Task<CommonResult> AddOrUpdate(QuzrtTaskOptions info)
        {
            return await baseApplication.AddOrUpdate<QuzrtTaskOptions>(info, BusinessType.quartz, BusinessLogType.writeLogToDataBase, null, o =>
            {
                DataCacheUtil.GetDataCacheUtil.RemoveData(TableAtributeUtil.GetTable<QuzrtTaskOptions>());
            });
        }

        /// <summary>
        /// 检查后台作业是否存在
        /// </summary>
        /// <param name="GroupName"></param>
        /// <param name="TaskName"></param>
        /// <param name="loginUserCode"></param>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<CommonResult> Checkgtname(string GroupName, string TaskName, string loginUserCode, string Id = "")
        {
            return await baseApplication.CheckDataExists<QuzrtTaskOptions>(BusinessType.quartz,
            BusinessLogType.writeLogToDataBase, o=>o.GroupName==GroupName && TaskName==TaskName && o.status!=-9, "检查后台作业是否存在", Id);
        }

        /// <summary>
        /// 删除后台作业信息
        /// </summary>
        /// <param name="schedulerFactory"></param>
        /// <param name="Id"></param>
        /// <param name="loginUserCode"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public async Task<CommonResult> Delete(ISchedulerFactory schedulerFactory,string Id, string loginUserCode, string type)
        {
            return await baseApplication.Delete<QuzrtTaskOptions>(Id, loginUserCode, type, BusinessType.quartz, (a, b, info) =>
            {
                schedulerFactory.Remove(baseApplication.mySqlSugar, info);
                return info.Id.ToString();
            });
        }

        /// <summary>
        /// 还原后台作业信息
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="loginUserCode"></param>
        /// <returns></returns>
        public async Task<CommonResult> Reduction(string Id, string loginUserCode)
        {
            return await baseApplication.Reduction<QuzrtTaskOptions>(Id, loginUserCode, BusinessType.quartz, (a, b, info) =>
            {
                return info.GroupName+"|"+info.TaskName;
            }, (o, info) =>
            {
                DataCacheUtil.GetDataCacheUtil.RemoveData(TableAtributeUtil.GetTable<QuzrtTaskOptions>());
            });
        }

    }
}
